#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include "snowboy/snowboy-detect-c-wrapper.h" // 唤醒词检测的头文件（在工程目录下）
#include "record.h"
#include "control.h"

void recording(snd_pcm_t *capture, char *buffer, FILE *pcm_file, snd_pcm_uframes_t period);

int main()
{
    int value, last_value;   // 定义当前值和上一次的值，用于检测状态变化
    // 录音相关变量
    snd_pcm_uframes_t period = 999; // 周期大小
    snd_pcm_t *capture = NULL; // 声音采集设备句柄
    char *buffer = NULL; // 存放音频数据的缓冲区
    FILE *pcm_file = NULL; // 录音文件

    long silence_start = 0; // 静音开始时候的时间戳
    long silence_time = 0; // 静音持续时长

    // 创建snowboy检测器
    SnowboyDetect* detector =  SnowboyDetectConstructor("common.res", "meeting.pmdl");
    if (!detector)
    {
        return EXIT_FAILURE;
    }

    SnowboyDetectSetSensitivity(detector, "0.7"); // 默认是0.5
    SnowboyDetectSetAudioGain(detector, 1.0);

    // 获取检测器支持的音频数据参数
    int bits = SnowboyDetectBitsPerSample(detector);    // 采样深度
    int channels = SnowboyDetectNumChannels(detector);  // 声道数量
    int rate = SnowboyDetectSampleRate(detector);       // 采样频率
    printf("采样深度: %d\n", bits);
    printf("声道数量: %d\n", channels);
    printf("采样频率: %d\n", rate);

    // 打开音频采集设备
    capture = record_start("hw:0,0", SND_PCM_FORMAT_S16_LE, channels, rate, &period);
    if(!capture)
    {
        SnowboyDetectDestructor(detector);
        return EXIT_FAILURE;
    }

    buffer = malloc(snd_pcm_frames_to_bytes(capture, period)); // 分配缓冲区
    if (!buffer)
    {
        perror("malloc");
        record_stop(capture);
        SnowboyDetectDestructor(detector);
        return EXIT_FAILURE;
    }

    pcm_file = fopen("output.pcm", "wb");
    if (!pcm_file)
    {
        perror("Error opening output file");
        free(buffer);         // 释放缓冲区
        record_stop(capture); // 关闭PCM设备
        SnowboyDetectDestructor(detector);
        return EXIT_FAILURE;
    }

    while(1)
    {
        silence_start = 0;
        silence_time = 0;

        snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); // 从PCM设备读取数据
        if (frames < 0)
        {
            fprintf(stderr, "Error from read: %s\n", snd_strerror(frames));
            snd_pcm_recover(capture, frames, 0);
        }

        // -2：静音
        // -1：错误
        // 0：有声音但不是唤醒词
        // n(>0)：检测到第n个唤醒词
        int status = SnowboyDetectRunDetection(detector, (int16_t*)buffer, snd_pcm_frames_to_bytes(capture, frames) / sizeof(int16_t), 0);
        if(status > 0)
        {
            printf("检测到唤醒词\n");
            printf("开始录音\n");
            while(1)
            {
                // 正在录音
                // printf("正在录音\n");
                recording(capture, buffer, pcm_file, period);
                status = SnowboyDetectRunDetection(detector, (int16_t*)buffer, snd_pcm_frames_to_bytes(capture, frames) / sizeof(int16_t), 0);
                // printf("status: %d\n", status);
                if (status == -2)
                {
                    if (silence_time == 0)
                    {
                        // 如果检测到静音并且静音时长为0（即首次检测到静音），记录静音开始时间戳
                        silence_start = time(NULL);
                        // printf("静音开始：%ld\n", silence_start);
                        silence_time = 1; // 手动设置静音时长不为0，防止之后静音时长得不到更新一直进入此条件，因为time(NULL)返回的时间戳以秒为单位
                    }
                    else
                    {
                        // 如果检测到静音并且静音时长不为0，计算静音时长
                        silence_time = time(NULL) - silence_start;
                        printf("静音时长：%ld 秒\n", silence_time);
                        if (silence_time <= 5)
                        {
                            // 静音时长小于等于5秒，继续录音
                            continue;
                        }
                        else
                        {
                            // 静音时长大于5秒，停止录音
                            break;
                        }
                    }  
                }
                else
                {
                    // 如果检测到不是静音，重置静音时长
                    silence_time = 0;
                }
            }
            printf("结束录音\n");
        }
    }
    
    record_stop(capture);

    SnowboyDetectDestructor(detector);

    return EXIT_SUCCESS; // 值为0
}

// 正在录音
void recording(snd_pcm_t *capture, char *buffer, FILE *pcm_file, snd_pcm_uframes_t period)
{
    snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); // 从PCM设备读取数据
    if (frames < 0)
    {
        fprintf(stderr, "Error from read: %s\n", snd_strerror(frames));
        snd_pcm_recover(capture, frames, 0); // 处理欠载和过载问题
    }

    fwrite(buffer, snd_pcm_frames_to_bytes(capture, frames), 1, pcm_file); // 将读取的数据写入文件
}
